/*
 * Copyright 2012 Marsrutai.lt
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package lt.marsrutai.mobile.android.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

import lt.marsrutai.mobile.android.model.enums.WeekdayType;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

/**
 * Represents all arrival times of the week for a particular stop
 * 
 * @author jvalskis
 */
public class StopArrivalTimes implements Parcelable {

    public static final Parcelable.Creator<StopArrivalTimes> CREATOR = new Parcelable.Creator<StopArrivalTimes>() {

        @Override
        public StopArrivalTimes createFromParcel(Parcel source) {
            return new StopArrivalTimes(source);
        }

        @Override
        public StopArrivalTimes[] newArray(int size) {
            return new StopArrivalTimes[size];
        }
    };

    /**
     * Multiple days can share the same arrival times - such days can be considered as one day group
     * This map holds common {@link ArrivalTime}s for a each {@link DayGroup} in the week 
     */
    private Map<DayGroup, List<ArrivalTime>> groupedArrivalTimes = new TreeMap<DayGroup, List<ArrivalTime>>();

    public StopArrivalTimes() {
    }
    
    public StopArrivalTimes(Parcel in) {
        int size = in.readInt();
        
        while (size-- > 0) {
            DayGroup key = in.readParcelable(DayGroup.class.getClassLoader());
            List<ArrivalTime> value = new ArrayList<ArrivalTime>();
            in.readList(value, DayGroup.class.getClassLoader());
            groupedArrivalTimes.put(key, value);
        }
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        Log.e("PARCEL", "out:start");
        dest.writeInt(groupedArrivalTimes.size());
        
        for (Entry<DayGroup, List<ArrivalTime>> entry : groupedArrivalTimes.entrySet()) {
            DayGroup key = entry.getKey();
            List<ArrivalTime> value = entry.getValue();

            dest.writeParcelable(key, flags);
            dest.writeList(value);
        }
        Log.e("PARCEL", "out:end");
    }

    @Override
    public int describeContents() {
        return 0;
    }
    
    /**
     * Adds arrival times for a specific day group
     * 
     * @param dayGroup
     * @param arrivalTimes
     */
    public void addArrivalTimes(DayGroup dayGroup, List<ArrivalTime> arrivalTimes) {
        groupedArrivalTimes.put(dayGroup, arrivalTimes);
    }

    /**
     * Finds arrival times for the provided day
     * 
     * @param day
     * @return Arrival times for the provided day if they exist, <code>null</code> otherwise
     */
    public List<ArrivalTime> getArrivalTimes(WeekdayType day) {
        for (Entry<DayGroup, List<ArrivalTime>> entry : groupedArrivalTimes.entrySet()) {
            if (entry.getKey().contains(day)) {
                return entry.getValue();
            }
        }
        return null;
    }

    /**
     * @return All arrival times. Keyed by {@link DayGroup} with list of {@link ArrivalTime}s as values
     */
    public Set<Entry<DayGroup, List<ArrivalTime>>> getArrivalTimes() {
        return groupedArrivalTimes.entrySet();
    }
}
